﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "GbmpApplicationEventHandler.h"
#include "FilePathManager.h"
#include "GbmpFileSystem.h"
#include "GbmpModifyJoinRelationship.h"
#include "GbmpProjectDocumentEventHandler.h"
#include "GmCommandAuthorizationFilter.h"
#include "GmGraphicsStyleFilter.h"
#include "IApplication.h"
#include "IApplicationEvent.h"
#include "IApplicationEventArgs.h"
#include "IImplementationUidTreeManager.h"
#include "NewGbmpDocumentInitializer.h"
#include "IExternalAddInManager.h"
#include "UiCommonDialog.h"
#include "IExternalAddIn.h"
#include "IMainWindow.h"
#include "IRibbonPage.h"
#include "IRibbonGroup.h"
#include "IRibbon.h"
#include "ICommandButtonDefinition.h"
#include "IControl.h"
#include "IUiDocumentViewManager.h"
#include "UiPlatformUtils.h"
#include "JournalUtils.h"
#include "DebugMessage.h"
#include "IJournalCheckData.h"
#include "ExternalDonetAddin.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

CREATE_DEBUG_MODE(TestApplicationEvent, L"测试程序启动事件。", gcmp::DebugModeGroup::DMGT_UI_AUTO_TEST, L"GDMPLab", L"2023-12-20", L"1.回放日志之前打开此调试标记位即可");

//////////////////////////////////////////////////////////////////////////

GbmpApplicationEventHandler::GbmpApplicationEventHandler()
{
}

GbmpApplicationEventHandler::~GbmpApplicationEventHandler()
{
    IApplication* pApp = IApplication::Get();
    if (pApp)
    {
        IApplicationEvent* pIApplicationEvent = pApp->GetApplicationEvent();
        if (pIApplicationEvent)
        {
            pIApplicationEvent->Delete(this);
        }
    }
}

void GbmpApplicationEventHandler::On(IApplicationEventArgs* pArgs)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs是空指针",L"GDMPLab",L"2024-03-30");

    if (pArgs->GetType() == ApplicationEventType::PreExecute)
    {        
        // 打开DebugMode：二维视图背面生成填充，便于脚本通过，根据产品需求，背面不需要填充
        DebugModeManager::Singleton().SetDebugMode(L"CreateHatchOnBackFace", true);

        // 打开DebugMode：ReportClassSchemaValidationErrorAsDebugWarn，将开发错误定义的成员变量报出来
        DebugModeManager::Singleton().SetDebugMode(L"ReportClassSchemaValidationErrorAsDebugWarn", true);

        // 打开DebugMode：CheckDocConsistencyWhenDocSave 在Document保存时检查文档一致性
        DebugModeManager::Singleton().SetDebugMode(L"CheckDocConsistencyWhenDocSave", true);

        // 打开DebugMode：取消默认Zoom范围限制，方便超大范围模型的测试
        DebugModeManager::Singleton().SetDebugMode(L"RemoveDefaultZoomLimit", true);

        // 打开DebugMode：截图验证时直接替换图片，仅用于批量替换脚本截图，慎用
        //DebugModeManager::Singleton().SetDebugMode(L"SnapshotValidatorReplaceMode", true);

        // 设置GCMP的BehaviorConfig文件路径，需在日志模块初始化之前
        std::wstring behaviorConfigPath = FileSystem::GetExeDirPath() + L"gbmp_gcmp_behavior_config.xml";
        FilePathManager::Get()->SetBehaviorConfigFilePath(behaviorConfigPath);

        // 注册过滤器
        OwnerPtr<GmGraphicsStyleFilter> pGmGraphicsStyleFilter = NEW_AS_OWNER_PTR(GmGraphicsStyleFilter);
        ICategoryAndGraphicsStyleFilter::SetCategoryAndGraphicsStyleFilter(TransferOwnership(pGmGraphicsStyleFilter));

        // 注册连接关系
        OwnerPtr<GbmpModifyJoinRelationship> pGmModifyJoinRelationship = NEW_AS_OWNER_PTR(GbmpModifyJoinRelationship);
        IModifyJoinRelationship::SetModifyJoinRelationship(TransferOwnership(pGmModifyJoinRelationship));

        // todo 需要考虑业务级别的初始化逻辑如何支持
        GbmpProjectDocumentEventHandler::GetInstance();
    }
    else if (pArgs->GetType() == ApplicationEventType::Executed)
    {
        if (DEBUG_MODE(TestApplicationEvent))
        {
            UiCommonDialog::ShowMessageBox(L"ApplicationEvent测试Executed", L"程序正在执行中：ApplicationEventType::Executed.", (int)UiCommonDialog::ButtonType::OK);
        }
        IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
        if (pUiDocViewMgr)
        {
            pUiDocViewMgr->RegisterDocumentOpenCallback(UiPlatformUtils::PrepareUI);
        }

        auto* pImplUidTreeMgr = IImplementationUidTreeManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pImplUidTreeMgr, L"implementation uid tree manager is null",L"GDMPLab",L"2024-03-30");
        pImplUidTreeMgr->BuildTree();

        gcmp::ExternalAddin::Get()->Setup();
    }
    else if (pArgs->GetType() == ApplicationEventType::PreClose) {
        
    }
    else if (pArgs->GetType() == ApplicationEventType::Closed)
    {
        if (DEBUG_MODE(TestApplicationEvent))
        {
            UiCommonDialog::ShowMessageBox(L"ApplicationEvent测试Closed", L"程序关闭了：ApplicationEventType::Closed.", (int)UiCommonDialog::ButtonType::OK);
        }
        IExternalAddInManager* pExternalAddInManager = IExternalAddInManager::Get();
        if (pExternalAddInManager)
        {
            pExternalAddInManager->UnloadAllAddIns();
        }

#ifdef _GNUF_WIP_REFACTOR_UIDOC_UIVIEW_LOGIC_
        // 清理垃圾桶，避免uiView没有及时清理造成ggp崩溃;
        gnuf::Utility::ClearTrashBin();
#endif // !_GNUF_WIP_REFACTOR_UIDOC_UIVIEW_LOGIC_
    }
}
